package cn.com.focu.im.sdk.service.user;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

import net.sf.json.JSONArray;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;
import cn.com.focu.im.sdk.service.ServiceOperator;
import cn.com.focu.im.sdk.service.annotation.Operator;
import cn.com.focu.im.sdk.service.csm.exception.CorpCustomerException;
import cn.com.focu.im.sdk.service.exception.ServiceException;
import cn.com.focu.im.sdk.service.user.entity.User;
import cn.com.focu.im.sdk.service.user.entity.UserDelete;
import cn.com.focu.im.sdk.service.user.entity.UserEmailExists;
import cn.com.focu.im.sdk.service.user.entity.UserGet;
import cn.com.focu.im.sdk.service.user.entity.UserList;
import cn.com.focu.im.sdk.service.user.entity.UserLoginNameExists;
import cn.com.focu.im.sdk.service.user.entity.UserLoginNumberExists;
import cn.com.focu.im.sdk.service.user.entity.UserMobileExists;
import cn.com.focu.im.sdk.service.user.entity.UserOnlineTime;
import cn.com.focu.im.sdk.service.user.entity.UserPasswd;
import cn.com.focu.im.sdk.service.user.entity.UserRegister;
import cn.com.focu.im.sdk.service.user.entity.UserRestore;
import cn.com.focu.im.sdk.service.user.entity.UserUpdate;
import cn.com.focu.im.sdk.service.user.exception.AuthenticationException;
import cn.com.focu.im.sdk.service.user.exception.UserDeleteException;
import cn.com.focu.im.sdk.service.user.exception.UserEmailExistsException;
import cn.com.focu.im.sdk.service.user.exception.UserGetException;
import cn.com.focu.im.sdk.service.user.exception.UserLoginNameExistsException;
import cn.com.focu.im.sdk.service.user.exception.UserLoginNumberExistsException;
import cn.com.focu.im.sdk.service.user.exception.UserMobileExistsException;
import cn.com.focu.im.sdk.service.user.exception.UserOnlineTimeException;
import cn.com.focu.im.sdk.service.user.exception.UserPasswdException;
import cn.com.focu.im.sdk.service.user.exception.UserRegisterException;
import cn.com.focu.im.sdk.service.user.exception.UserRestoreException;
import cn.com.focu.im.sdk.service.user.exception.UserUpdateException;

/**
 * 用户操作
 * 
 * @作者 yeabow
 * @创建日期 Jul 12, 2011 4:52:08 PM
 * @版本 v1.0.0
 */
@Operator("user")
public class UserOperator extends ServiceOperator {

	private UserOperator() {
	}

	private static class UserOperatorHolder {
		static UserOperator userOperator = new UserOperator();
	}

	/**
	 * 还原指定账号
	 * 
	 * @param loginNumber
	 * @return
	 * @throws UserRestoreException
	 */
	public boolean restore(String loginNumber) throws UserRestoreException {
		try {
			JSONObject json = JSONObject
					.fromObject(new UserRestore(loginNumber));
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("jsonString", URLEncoder
					.encode(json.toString(), "UTF-8"));
			String rs = postReturnString(params);
			if (log.isDebugEnabled()) {
				log.debug(rs);
			}
			Integer uid = Integer.valueOf(rs);
			if (uid > 0) {
				return true;
			}
			switch (uid) {
			case 0:
				throw new UserRestoreException(uid, "JSON格式有误!");
			default:
				throw new UserRestoreException(uid, OTHER_ERROR);
			}
		} catch (NumberFormatException e) {
			throw new UserRestoreException("没有返回预期的数据!", e);
		} catch (UnsupportedEncodingException e) {
			throw new UserRestoreException("参数传递有误!", e);
		} catch (IOException e) {
			throw new ServiceException(CANNOT_CONNECT_TO_SERVER);
		}
	}

	/**
	 * 还原指定账号
	 * 
	 * @param uid
	 * @return
	 * @throws UserRestoreException
	 */
	public boolean restore(Integer uid) throws UserRestoreException {
		try {
			JSONObject json = JSONObject.fromObject(new UserRestore(uid));
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("jsonString", URLEncoder
					.encode(json.toString(), "UTF-8"));
			String rs = postReturnString(params);
			if (log.isDebugEnabled()) {
				log.debug(rs);
			}
			Integer r = Integer.valueOf(rs);
			if (r > 0) {
				return true;
			}
			switch (r) {
			case 0:
				throw new UserRegisterException(uid, "JSON格式有误!");
			default:
				throw new UserRegisterException(uid, OTHER_ERROR);
			}
		} catch (NumberFormatException e) {
			throw new UserPasswdException("没有返回预期的数据!", e);
		} catch (UnsupportedEncodingException e) {
			throw new UserPasswdException("参数传递有误!", e);
		} catch (IOException e) {
			throw new ServiceException(CANNOT_CONNECT_TO_SERVER);
		}
	}

	/**
	 * 用户注册
	 * 
	 * @param userRegister
	 *            注册实体
	 * @return 当前注册用户的编号
	 * @throws UserRegisterException
	 *             用户注册异常
	 */
	public Integer register(UserRegister userRegister)
			throws UserRegisterException {
		try {
			JSONObject json = JSONObject.fromObject(userRegister);
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("jsonString", URLEncoder
					.encode(json.toString(), "UTF-8"));
			String rs = postReturnString(params);
			if (log.isDebugEnabled()) {
				log.debug(rs);
			}
			Integer uid = Integer.valueOf(rs);
			if (uid > 0) {
				return uid;
			}
			switch (uid) {
			case -1:
				throw new UserRegisterException(uid, "没有指定用户密码[password]!");
			case -2:
				throw new UserRegisterException(uid, "别名[loginName]包含不允许注册的词语!");
			case -3:
				throw new UserRegisterException(uid, "别名[loginName]已经存在!");
			case -4:
				throw new UserRegisterException(uid, "Email[loginName]格式有误!");
			case -5:
				throw new UserRegisterException(uid, "Email不允许注册[若不允许重复]");
			case -6:
				throw new UserRegisterException(uid, "Email不允许登录，已经被其他账号使用.");
			case -7:
				throw new UserRegisterException(uid, "IM账号[loginNumber]已经存在!");
			case -8:
				throw new UserRegisterException(uid,
						"IM账号[loginNumber]为必输项[random=false]");
			case -9:
				throw new UserRegisterException(uid, "手机号码不允许登录,已经被其他账号使用.");
			case -10:
				throw new UserRegisterException(uid, "LoginNumber必须为数字.");
			case -11:
				throw new UserRegisterException(uid,
						"LoginNumber必须大于等于10000,且不能为手机号码");
			case -12:
				throw new UserRegisterException(uid,
						"没有足够的号码进行分配,请在系统管理->号码池管理->IM号码管理 中进行生成.");
			default:
				throw new UserRegisterException(uid, OTHER_ERROR);
			}
		} catch (NumberFormatException e) {
			throw new UserPasswdException("没有返回预期的数据!", e);
		} catch (UnsupportedEncodingException e) {
			throw new UserPasswdException("参数传递有误!", e);
		} catch (IOException e) {
			throw new ServiceException(CANNOT_CONNECT_TO_SERVER);
		}
	}

	/**
	 * 获取在线长[分钟]
	 * 
	 * @param userOnlineTime
	 *            在线时长实体
	 * @return
	 * @throws UserOnlineTimeException
	 *             获取在线时长异常
	 */
	public Integer onlineTime(UserOnlineTime userOnlineTime)
			throws UserOnlineTimeException {
		try {
			JSONObject json = JSONObject.fromObject(userOnlineTime);
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("jsonString", URLEncoder
					.encode(json.toString(), "UTF-8"));
			String rs = postReturnString(params);
			if (log.isDebugEnabled()) {
				log.debug(rs);
			}
			Integer time = Integer.valueOf(rs);
			if (time >= 0) {
				return time;
			}

			switch (time) {
			case -1:
				throw new UserOnlineTimeException(time, "找不到要查询的用户!");
			case -2:
				throw new UserOnlineTimeException(time, "参数格式有误!不是标准的json");
			case -3:
				throw new UserOnlineTimeException(time,
						"参数不足,缺少用户名[loginName]字段或传入的值为空值!");
			case -4:
				throw new UserOnlineTimeException(time,
						"参数不足,缺少用户ID[uid]字段或传入ID无效(必须大于0)!");
			case -5:
				throw new UserOnlineTimeException(time,
						"参数不足,缺少IM帐号[loginNumer]字段或传入的值为空值!");
			default:
				throw new UserOnlineTimeException(time, OTHER_ERROR);
			}
		} catch (NumberFormatException e) {
			throw new UserPasswdException("没有返回预期的数据!", e);
		} catch (UnsupportedEncodingException e) {
			throw new UserPasswdException("参数传递有误!", e);
		} catch (IOException e) {
			throw new ServiceException(CANNOT_CONNECT_TO_SERVER);
		}
	}

	public User get(UserGet userGet) throws UserGetException {
		try {
			JSONObject json = JSONObject.fromObject(userGet);
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("jsonString", URLEncoder
					.encode(json.toString(), "UTF-8"));
			String rs = postReturnString(params);
			if (log.isDebugEnabled()) {
				log.debug(rs);
			}
			try {
				JSONObject r = JSONObject.fromObject(rs);
				try {
					if (!r.getBoolean("success")) {
						int status = r.getInt("error");
						switch (r.getInt("error")) {
						case 20:
							throw new UserGetException(status, "帐号提供有误!");
						default:
							throw new UserGetException(status, OTHER_ERROR);
						}
					} else {
						if (r.has("result")) {
							JSONObject result = r.getJSONObject("result");
							return new User(result);
						} else {
							return null;
						}
					}
				} catch (JSONException e) {
				}
			} catch (JSONException e) {
				throw new UserGetException("返回数据格式有误!", e);
			}
			return null;
		} catch (UnsupportedEncodingException e) {
			throw new UserPasswdException("参数传递有误!", e);
		} catch (IOException e) {
			throw new ServiceException(CANNOT_CONNECT_TO_SERVER);
		}
	}

	public void passwd(UserPasswd userPasswd) throws UserPasswdException {
		try {
			JSONObject json = JSONObject.fromObject(userPasswd);
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("jsonString", URLEncoder
					.encode(json.toString(), "UTF-8"));
			String rs = postReturnString(params);
			if (log.isDebugEnabled()) {
				log.debug(rs);
			}
			Integer status = Integer.valueOf(rs);
			if (status > 0) {
				return;
			}

			switch (status) {
			case 0:
				throw new UserPasswdException(status, "没有提供相应的参数!");
			case -1:
				throw new UserPasswdException(status, "服务器处理失败!");
			case -2:
				throw new UserPasswdException(status, "帐号提供有误!");
			case -3:
				throw new UserPasswdException(status, "密码[password]不允许修改为空!");
			default:
				throw new UserPasswdException(status, OTHER_ERROR);
			}

		} catch (NumberFormatException e) {
			throw new UserPasswdException("没有返回预期的数据!", e);
		} catch (UnsupportedEncodingException e) {
			throw new UserPasswdException("参数传递有误!", e);
		} catch (IOException e) {
			throw new ServiceException(CANNOT_CONNECT_TO_SERVER);
		}
	}

	public void update(UserUpdate userUpdate) throws UserUpdateException {
		try {
			JSONObject json = JSONObject.fromObject(userUpdate);
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("jsonString", URLEncoder
					.encode(json.toString(), "UTF-8"));
			String rs = postReturnString(params);
			if (log.isDebugEnabled()) {
				log.debug(rs);
			}
			Integer status = Integer.valueOf(rs);
			if (status > 0) {
				return;
			}

			switch (status) {
			case 0:
				throw new UserUpdateException(status, "没有提供相应的参数!");
			case -3:
				throw new UserUpdateException(status, "别名[loginName]不能为空,且大于0!");
			case -4:
				throw new UserUpdateException(status, "用户编号[uid]不能为空!");
			case -5:
				throw new UserUpdateException(status, "IM帐号[loginNumber]不能为空!");
			case -6:
				throw new UserUpdateException(status, "Email格式有误!");
			case -7:
				throw new UserUpdateException(status, "Email已经被其他帐号暂用,不允许登录!");
			case -8:
				throw new UserUpdateException(status, "IM帐号已经被占用!");
			default:
				throw new UserUpdateException(status, OTHER_ERROR);
			}

		} catch (NumberFormatException e) {
			throw new UserUpdateException("没有返回预期的数据!", e);
		} catch (UnsupportedEncodingException e) {
			throw new UserUpdateException("参数传递有误!", e);
		} catch (IOException e) {
			throw new ServiceException(CANNOT_CONNECT_TO_SERVER);
		}
	}
	
	public void offline(String ... accounts) throws UserDeleteException {
		try {
			JSONArray json = JSONArray.fromObject(accounts);
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("jsonString", URLEncoder
					.encode(json.toString(), "UTF-8"));
			String rs = postReturnString(params);
			if (log.isDebugEnabled()) {
				log.debug(rs);
			}
		} catch (UnsupportedEncodingException e) {
			throw new UserDeleteException("参数传递有误!", e);
		} catch (IOException e) {
			throw new ServiceException(CANNOT_CONNECT_TO_SERVER);
		}
	}

	public void delete(UserDelete userDelete) throws UserDeleteException {
		try {
			JSONObject json = JSONObject.fromObject(userDelete);
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("jsonString", URLEncoder
					.encode(json.toString(), "UTF-8"));
			String rs = postReturnString(params);
			if (log.isDebugEnabled()) {
				log.debug(rs);
			}
			Integer status = Integer.valueOf(rs);
			if (status > 0) {
				return;
			}

			switch (status) {
			case -1:
				throw new UserDeleteException(status, "没有提供相应的参数");
			default:
				throw new UserDeleteException(status, OTHER_ERROR);
			}
		} catch (NumberFormatException e) {
			throw new UserDeleteException("没有返回预期的数据!", e);
		} catch (UnsupportedEncodingException e) {
			throw new UserDeleteException("参数传递有误!", e);
		} catch (IOException e) {
			throw new ServiceException(CANNOT_CONNECT_TO_SERVER);
		}
	}

	public Integer isLoginNumberExists(
			UserLoginNumberExists userLoginNumberExists)
			throws UserLoginNumberExistsException {
		try {
			JSONObject json = JSONObject.fromObject(userLoginNumberExists);
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("jsonString", URLEncoder
					.encode(json.toString(), "UTF-8"));
			String rs = postReturnString(params);
			if (log.isDebugEnabled()) {
				log.debug(rs);
			}
			Integer status = Integer.valueOf(rs);
			if (status > 0) {
				return status;
			}

			switch (status) {
			case -1:
				return status;
			case -2:
				throw new UserLoginNumberExistsException(status, "编号[uid]不存在!");
			default:
				throw new UserLoginNumberExistsException(status, OTHER_ERROR);
			}
		} catch (NumberFormatException e) {
			throw new UserLoginNumberExistsException("没有返回预期的数据!", e);
		} catch (UnsupportedEncodingException e) {
			throw new UserLoginNumberExistsException("参数传递有误!", e);
		} catch (IOException e) {
			throw new ServiceException(CANNOT_CONNECT_TO_SERVER);
		}
	}

	public Integer authentication(String account, String password)
			throws AuthenticationException {

		try {
			JSONObject json = new JSONObject();

			json.put("loginName", account);
			json.put("password", password);

			Map<String, Object> params = new HashMap<String, Object>();

			params.put("jsonString", URLEncoder
					.encode(json.toString(), "UTF-8"));

			String rs = postReturnString(params);

			if (log.isDebugEnabled()) {
				log.debug(rs);
			}
			Integer status = Integer.valueOf(rs);
			if (status > 0) {
				return status;
			}

			switch (status) {
			case -1:
				throw new AuthenticationException(status, "账号错误!");
			case -2:
				throw new AuthenticationException(status, "密码错误!");
			default:
				throw new AuthenticationException(status, OTHER_ERROR);
			}
		} catch (NumberFormatException e) {
			throw new AuthenticationException("没有返回预期的数据!", e);
		} catch (UnsupportedEncodingException e) {
			throw new AuthenticationException("参数传递有误!", e);
		} catch (IOException e) {
			throw new ServiceException(CANNOT_CONNECT_TO_SERVER);
		}
	}

	public Integer isLoginNameExists(UserLoginNameExists userLoginNameExists)
			throws UserLoginNameExistsException {
		try {
			JSONObject json = JSONObject.fromObject(userLoginNameExists);
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("jsonString", URLEncoder
					.encode(json.toString(), "UTF-8"));
			String rs = postReturnString(params);
			if (log.isDebugEnabled()) {
				log.debug(rs);
			}
			Integer status = Integer.valueOf(rs);
			if (status > 0) {
				return status;
			}

			switch (status) {
			case -1:
				return status;
			case -2:
				throw new UserLoginNameExistsException(status, "编号[uid]不存在!");
			default:
				throw new UserLoginNameExistsException(status, OTHER_ERROR);
			}
		} catch (NumberFormatException e) {
			throw new UserLoginNameExistsException("没有返回预期的数据!", e);
		} catch (UnsupportedEncodingException e) {
			throw new UserLoginNameExistsException("参数传递有误!", e);
		} catch (IOException e) {
			throw new ServiceException(CANNOT_CONNECT_TO_SERVER);
		}
	}

	public Boolean isEmailExists(UserEmailExists userEmailExists)
			throws UserEmailExistsException {
		try {
			JSONObject json = JSONObject.fromObject(userEmailExists);
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("jsonString", URLEncoder
					.encode(json.toString(), "UTF-8"));
			String rs = postReturnString(params);
			if (log.isDebugEnabled()) {
				log.debug(rs);
			}
			Integer status = Integer.valueOf(rs);
			if (status > 0) {
				return true;
			}

			switch (status) {
			case -3:
				return false;
			case -1:
				throw new UserEmailExistsException(status, "邮箱[Email]为空或未传入值!");
			case -2:
				throw new UserEmailExistsException(status, "编号[uid]不存在!");
			default:
				throw new UserEmailExistsException(status, OTHER_ERROR);
			}
		} catch (NumberFormatException e) {
			throw new UserEmailExistsException("没有返回预期的数据!", e);
		} catch (UnsupportedEncodingException e) {
			throw new UserEmailExistsException("参数传递有误!", e);
		} catch (IOException e) {
			throw new ServiceException(CANNOT_CONNECT_TO_SERVER);
		}
	}

	public Boolean isMobileExists(UserMobileExists userMobileExists)
			throws UserMobileExistsException {
		try {
			JSONObject json = JSONObject.fromObject(userMobileExists);
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("jsonString", URLEncoder
					.encode(json.toString(), "UTF-8"));
			String rs = postReturnString(params);
			if (log.isDebugEnabled()) {
				log.debug(rs);
			}
			Integer status = Integer.valueOf(rs);
			if (status > 0) {
				return true;
			}

			switch (status) {
			case -3:
				return false;
			case -1:
				throw new UserMobileExistsException(status, "手机号为空或未传入值!");
			case -2:
				throw new UserMobileExistsException(status, "编号[uid]不存在!");
			default:
				throw new UserMobileExistsException(status, OTHER_ERROR);
			}
		} catch (NumberFormatException e) {
			throw new UserMobileExistsException("没有返回预期的数据!", e);
		} catch (UnsupportedEncodingException e) {
			throw new UserMobileExistsException("参数传递有误!", e);
		} catch (IOException e) {
			throw new ServiceException(CANNOT_CONNECT_TO_SERVER);
		}
	}

	public Integer administratorLogin(String account, String password)
			throws AuthenticationException {

		try {
			JSONObject json = new JSONObject();

			json.put("loginName", account);
			json.put("password", password);

			Map<String, Object> params = new HashMap<String, Object>();

			params.put("jsonString", URLEncoder
					.encode(json.toString(), "UTF-8"));

			String rs = postReturnString(params);

			if (log.isDebugEnabled()) {
				log.debug(rs);
			}
			Integer status = Integer.valueOf(rs);
			if (status > 0) {
				return status;
			}

			switch (status) {
			case -1:
				throw new AuthenticationException(status, "账号错误!");
			case -2:
				throw new AuthenticationException(status, "密码错误!");
			default:
				throw new AuthenticationException(status, OTHER_ERROR);
			}
		} catch (NumberFormatException e) {
			throw new AuthenticationException("没有返回预期的数据!", e);
		} catch (UnsupportedEncodingException e) {
			throw new AuthenticationException("参数传递有误!", e);
		} catch (IOException e) {
			throw new ServiceException(CANNOT_CONNECT_TO_SERVER);
		}
	}

	public String getCustomUserListReturnPage(UserList userList) {
		String rs = "";
		try {
			JSONObject json = JSONObject.fromObject(userList);
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("jsonString", URLEncoder
					.encode(json.toString(), "UTF-8"));
			rs = postReturnString(params);
			if (log.isDebugEnabled()) {
				log.debug(rs);
			}

		} catch (IOException e) {
			throw new ServiceException(CANNOT_CONNECT_TO_SERVER);
		} catch (Exception e) {
			throw new CorpCustomerException(e.getMessage(), e);
		}
		return rs;
	}

	public Integer getUidByAccount(String account)
			throws AuthenticationException {

		try {
			JSONObject json = new JSONObject();

			json.put("account", account);

			Map<String, Object> params = new HashMap<String, Object>();

			params.put("jsonString", URLEncoder
					.encode(json.toString(), "UTF-8"));

			String rs = postReturnString(params);

			if (log.isDebugEnabled()) {
				log.debug(rs);
			}
			Integer status = Integer.valueOf(rs);
			if (status > 0) {
				return status;
			}

			switch (status) {
			case -1:
				throw new AuthenticationException(status, "账号错误!");
			case -2:
				throw new AuthenticationException(status, "密码错误!");
			default:
				throw new AuthenticationException(status, OTHER_ERROR);
			}
		} catch (NumberFormatException e) {
			throw new AuthenticationException("没有返回预期的数据!", e);
		} catch (UnsupportedEncodingException e) {
			throw new AuthenticationException("参数传递有误!", e);
		} catch (IOException e) {
			throw new ServiceException(CANNOT_CONNECT_TO_SERVER);
		}
	}

	public static UserOperator getInstance() {
		return UserOperatorHolder.userOperator;
	}
}
